import java.util.Stack;

public class Solve {
    /**
     * ops栈用来存放操作符，nums栈用来存放操作数
     * 当遇到(的时候直接将(添加到ops栈中
     * 当遇到)的时候将()之内的运算执行，然后将执行的结果放回nums栈中
     * 当遇到数字的时候，将完整的数字放在nums栈中
     * 当遇到操作符的时候，需要将站内优先级高于等于当前操作符优先级的运算执行了，然后再将当前操作符添加进ops栈中
     * 也就是说当遇到+-操作符的时候，可以将(之内的所有的运算都执行了，而遇到*、/的时候则只能将括号之内的+-运算执行了
     * 还有一个问题需要考虑，就是需要对一元负号做出处理，例如-1+2，这时候按照前面的规则，nums栈中的运算数就只有一个
     * 那么这时新增一个0就可以解决
     * @param s
     * @return
     */
    public int solve (String s) {
        // write code here
        // ops栈用来存放操作符
        Stack<Character> ops = new Stack<>();
        // nums数组用来存放数字
        Stack<Integer> nums = new Stack<>();
        int index = 0;
        s = s.replaceAll(" ", "");
        char[] ss = s.toCharArray();
        while (index < ss.length) {
            if (ss[index] == '(') {
                ops.add(ss[index++]);
                continue;
            } else if (ss[index] == ')') {
                // 当遇到)的时候将()之间的操作都执行了
                while (!ops.isEmpty() && ops.peek() != '(') {
                    calculate(nums, ops);
                }
                // 将(弹出来
                ops.pop();
                index++;
            } else {
                // 数字或者操作符
                // 操作符
                if (ss[index] == '*' || ss[index] == '/') {
                    // 当遇到*或者/的时候，可以将操作符栈内的*和/都进行预算
                    while (!ops.isEmpty() && ops.peek() != '('
                            && (ops.peek() == '*' || ops.peek() == '/')) {
                        calculate(nums, ops);
                    }
                    ops.add(ss[index++]);
                } else if (ss[index] == '+' || ss[index] == '-') {
                    if (index == 0 && ss[index] == '-') {
                        nums.add(0);
                    } else {
                        while (!ops.isEmpty() && ops.peek() != '(') {
                            calculate(nums, ops);
                        }
                    }
                    ops.add(ss[index++]);
                } else {
                    // 数字
                    int num = 0;
                    while (index < ss.length
                            && ss[index] >= '0' && ss[index] <= '9') {
                        num = num * 10 + (ss[index++] - '0');
                    }
                    nums.add(num);
                }
            }
        }
        while (!ops.isEmpty()) {
            calculate(nums, ops);
        }
        return nums.pop();
    }

    private void calculate(Stack<Integer> nums, Stack<Character> ops) {
        if (nums.size() < 2 || ops.isEmpty()) return;
        int num2 = nums.pop();
        int num1 = nums.pop();
        char operation = ops.pop();
        if (operation == '+') {
            nums.add(num1 + num2);
        } else if (operation == '-') {
            nums.add(num1 - num2);
        } else if (operation == '*') {
            nums.add(num1 * num2);
        } else {
            nums.add(num1 / num2);
        }
    }

    public static void main(String[] args) {
        Solve solve = new Solve();
        System.out.println(solve.solve("(2*(3-4))*5"));
    }
}
